/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include <mutex>
#include <any>
#include <数据工具库.h>

#include "引擎枚举数据.h"
#include "引擎数据类型.h"
#include "结构数据.h"

#include "shader_line.h"
#include "shader_std.h"
#include "shader_mesh.h"


S_板载缓存* f_buffer_创建拷贝缓存(S_板载缓存& 主缓存对象);


typedef void(*fp_GPU_BufferUpdate)(struct S_板载缓存* buf);

struct S_板载缓存 {
	S_设备环境	m_Ctx;

	S_板载缓存* m_主内存;
	void*		m_mappedPtr;

	uint64		m_Size;
	uint32		m_Offset;
	uint64		elt_capacity;
	uint64		m_GPU_Address;
	
	S_内存分配	m_分配器;
	
	std::mutex	m_分配内存锁;
	std::mutex	m_分配块内存锁;

	bool		m_预分配空间;
	bool		m_流;
	

	E_板载缓存类型      m_Type;
	fp_GPU_BufferUpdate m_Update;

	virtual void	f_fillData(const void* data, uint64 bitSize) = 0;

	virtual void	f_map()		= 0;
	virtual void	f_unmap()	= 0;

	virtual void	f_resize(uint64 bitSize) = 0;
	virtual void	f_copy(S_结构指针 sObj) = 0;
	//virtual void	f_change板载缓存(E_板载缓存类型 memType) = 0;
	virtual void	f_insert(uint64 offset, void* data, uint64 size) {}

	//virtual void	f_resize(uint64 bitSize, uint64 offset) {};



	S_板载缓存():
		m_Ctx({}),
		m_主内存(nullptr),
		m_mappedPtr(nullptr),
		m_Update(nullptr),
		m_GPU_Address(0),
		elt_capacity(0),
		m_Offset(0),
		m_Size(0),
		m_预分配空间(true),
		m_流(false)
	{
		m_分配器.maxNum = 0;
	}
	virtual ~S_板载缓存() {};
};







//------------------------------ 全局统一分配内存 -------------------------------------------


S_GPU偏移大小	f_buf_galloc(S_板载缓存* buf, uint64 num);
void			f_buf_gfree(S_板载缓存* buf, S_GPU偏移大小& 块);
void			f_bm_resize(S_GPU内存块& 块, uint64 newSize);
void			f_bm_erase(S_GPU内存块& 块);

Inline S_GPU内存块 f_bm_alloc(S_板载缓存* buf, uint64 num) {
	if (num) {
		return {buf, f_buf_galloc(buf, num), nullptr, nullptr};
	}
	else {
		return {buf, {}, nullptr, nullptr };
	}
}
//Inline void f_buf_free(S_GPU内存块索引& 块) {
//	f_buf_gfree(块.m_Buf, 块.m_Mem);
//	块.m_Mem = {};
//}




template <typename T>
class C_VkStagingAllocator {
	S_板载缓存* m_buffer;
	S_GPU内存块 m_内存块;

	//S_GPU偏移大小 m_内存块;
public:
	//C_VkStagingAllocator() noexcept {};

	typedef T value_type;
	using pointer = T*;
	using size_type = std::size_t;
	//char* mem_ptr;				// 预分配内存地址（char*方便偏移计算）
	//std::size_t total_size;		// 总大小
	std::size_t used_offset = 0;		// 已用偏移（复用核心）
	//std::size_t alignment;		// 对齐要求

	// 拷贝构造
	C_VkStagingAllocator(const C_VkStagingAllocator<T>& other) noexcept {
		m_buffer = other.m_buffer;
		m_内存块 = other.m_内存块;
		std::cout<<"拷贝构造\n";
	}

	// 跨类型拷贝构造
	template <typename U>
	C_VkStagingAllocator(const C_VkStagingAllocator<U>& other) noexcept {
		m_buffer = other.m_buffer;
		m_内存块 = other.m_内存块;
		std::cout<<"跨类型拷贝构造\n";
	}

	C_VkStagingAllocator(S_板载缓存* buf) noexcept  : m_buffer(buf) {
		if (!m_buffer->m_主内存) {
			m_buffer->m_主内存 = f_buffer_创建拷贝缓存(*m_buffer);
		}
		m_内存块 = f_bm_alloc(m_buffer->m_主内存, 1);
	}


	T* allocate(std::size_t n) {
		f_bm_resize(m_内存块, n);
		std::cout<<"分配缓存\n";
		//auto p = calloc(n, sizeof(T));
		//return (T*)p;
		return (T*)m_buffer->m_主内存->m_mappedPtr;
	}

	void deallocate(T* /*p*/, std::size_t /*n*/) noexcept {
		// 仅复用，不释放物理内存
		f_bm_erase(m_内存块);
		std::cout<<"销毁缓存\n";
	}

	template <typename U>
	friend class C_VkStagingAllocator;
};


template <typename T, typename U>
bool operator==(const C_VkStagingAllocator<T>& a, const C_VkStagingAllocator<U>& b) noexcept {
	return a.mem_ptr == b.mem_ptr && a.total_size == b.total_size;
}

template <typename T, typename U>
bool operator!=(const C_VkStagingAllocator<T>& a, const C_VkStagingAllocator<U>& b) noexcept {
	return !(a == b);
}




typedef struct {
	S_板载缓存**	m_Grup;
	uint32			m_Num;
}S_板载缓存组;




typedef struct {
	S_板载缓存*		m_视图矩阵;
	S_结构指针	m_GPU参数;
	S_结构指针	m_2D笔刷;
}S_2D绘制GPU全局参数;






/*#ifdef _DEBUG  

S_板载缓存* f_buf_create板载缓存(S_设备环境 ctx, uint16 offset, E_板载缓存类型 type = E_板载缓存类型::e_VBO, uint64 size = 0, const std::string fileName = (__FILE__), uint32 行号 = __LINE__);
S_板载缓存* f_buf_create板载缓存(S_设备环境 ctx, E_板载缓存类型 type, uint32 typeflags, uint16 offset, uint64 size, const std::string fileName = (__FILE__), uint32 行号 = __LINE__);
S_板载缓存* f_buf_create板载缓存(S_设备环境 ctx, E_板载缓存类型 type, uint16 offset, const std::string fileName = (__FILE__), uint32 行号 = __LINE__);

#else



#endif*/

EngineAPI_EXPORT S_板载缓存* f_buf_create板载缓存(S_设备环境& ctx, uint16 offset, E_板载缓存类型 type = E_板载缓存类型::e_VBO, uint64 size = 0);
EngineAPI_EXPORT S_板载缓存* f_buf_create板载缓存(S_设备环境& ctx, E_板载缓存类型 type, uint32 typeflags, uint16 offset, uint64 size);
EngineAPI_EXPORT S_板载缓存* f_buf_create板载缓存(S_设备环境& ctx, E_板载缓存类型 type, uint16 offset);

S_板载缓存* f_buffer_创建流(S_设备环境& ctx, E_板载缓存类型 type, uint16 offset);


EngineAPI_EXPORT void		f_buf_release板载缓存(S_板载缓存* obj);
EngineAPI_EXPORT void        f_buf_释放所有();

EngineAPI_EXPORT uint32 f_getAPI缓存类型(E_板载缓存类型 memType);
EngineAPI_EXPORT uint32 f_getAPI光追加速缓存类型(E_板载缓存类型 memType);
EngineAPI_EXPORT uint32 f_get缓存布局类型(E_板载缓存类型 memType);

EngineAPI_EXPORT void f_fill板载缓存(S_板载缓存* obj, const std::vector<vec3>& data, E_板载缓存类型 memType, S_设备环境& ctx);
EngineAPI_EXPORT void f_fill板载缓存(S_板载缓存* obj, const std::vector<uint32>& data, E_板载缓存类型 memType, S_设备环境& ctx);

EngineAPI_EXPORT void f_fill板载缓存(S_板载缓存* obj, const std::vector<Mat44f>& data);

EngineAPI_EXPORT void f_fill板载缓存(S_板载缓存* obj, const Mat44f* data, uint64 offset);

EngineAPI_EXPORT void f_buf_set(S_板载缓存* obj, int8 val);

EngineAPI_EXPORT void f_buf_fill(S_板载缓存* obj, const void* val, uint64 num);

Inline void f_buf_get(S_板载缓存* buf, void* val, uint64 num) {
	buf->f_map();
	memcpy(val, buf->m_mappedPtr, num);
	buf->f_unmap();
}



EngineAPI_EXPORT void f_buf_resize(S_板载缓存* obj, uint64 size);
EngineAPI_EXPORT void f_buf_erase(S_板载缓存* obj, uint32 loc, uint32 num = 1);
EngineAPI_EXPORT bool f_resize板载缓存_Up(S_板载缓存* obj, uint64 size);
//EngineAPI_EXPORT void f_change板载缓存(S_板载缓存* obj, E_板载缓存类型 memType);




Inline void f_buf_fill板载缓存(S_板载缓存* obj, const void* data, uint64 count) {
	obj->m_Size = count;
	obj->f_fillData(data, obj->m_Size * obj->m_Offset);
}

template<typename T>
void f_buf_fill板载缓存(S_板载缓存* obj, const std::vector<T>& data, E_板载缓存类型 memType) {
	obj->m_Size = data.size();
	obj->m_Offset = sizeof(T);
	obj->m_Type = memType;
	obj->f_fillData(data.data(), data.size() * sizeof(T));
}

template<typename T>
void f_buf_fill板载缓存(S_板载缓存* obj, const std::vector<T>& data) {
	obj->m_Size = data.size();
	obj->m_Offset = sizeof(T);
	obj->f_fillData(data.data(), obj->m_Size * obj->m_Offset);
}


template<typename T>
void f_buf_fill板载缓存(S_板载缓存* obj, const T* data, uint64 num, E_板载缓存类型 memType) {
	obj->m_Size = num;
	obj->m_Type = memType;
	obj->f_fillData(data, num * obj->m_Offset);
}



Inline void f_buf_fill板载缓存(S_板载缓存* obj, uint16 bitSize, uint64 num, const void* data, E_板载缓存类型 memType) {
	obj->m_Size = num;
	obj->m_Type = memType;
	obj->m_Offset = bitSize;
	obj->f_fillData(data, num * obj->m_Offset);
}


Inline void f_buf_fill(S_板载缓存* obj, uint64 offset, const void* data, uint64 字节数) {
	obj->f_map();
	memcpy(&(((uint8*)obj->m_mappedPtr)[offset]), data, 字节数);
	obj->f_unmap();
}

//注意一般情况下不要填指针类型
template<typename T>
void f_buf_set(S_板载缓存* obj, uint64 offset, const T& data) {
	obj->f_map();
	((T*)(obj->m_mappedPtr))[offset] = data;
	obj->f_unmap();
}

template<typename T>
void f_copy板载缓存array(S_板载缓存* obj, const T* data, uint64 count) {
	obj->f_map();
	//for (uint64 i=0; i < count; ++i) {
	//	((T*)(obj->m_mappedPtr))[i] = data[i];
	//}
	memcpy(obj->m_mappedPtr, data, sizeof(T) * count);
	obj->f_unmap();
}

template<typename T>
void f_copy板载缓存array(S_板载缓存* obj, uint64 offset, const T* data, uint64 count) {
	obj->f_map();
	memcpy(&(((T*)obj->m_mappedPtr)[offset]), data, sizeof(T) * count);
	obj->f_unmap();
}


Inline void f_buf_copy板载缓存(S_板载缓存* b1, S_板载缓存* b2) {
	uint64 num = b2->m_Size;
	b1->m_Offset = b2->m_Offset;

	f_buf_resize(b1, num);

	b1->f_map();
	b2->f_map();
	//for (uint64 i = 0; i < num * b1->m_Offset; ++i) {
	//	((uint8*)b1->m_mappedPtr)[i] = ((uint8*)b2->m_mappedPtr)[i];
	//}
	memcpy(b1->m_mappedPtr, b2->m_mappedPtr, num * b1->m_Offset);
	b1->f_unmap();
	b2->f_unmap();
}

Inline void f_buf_copy板载缓存(S_板载缓存* b1, void* b2) {
	b1->f_map();
	memcpy(b1->m_mappedPtr, b2, b1->m_Size * b1->m_Offset);
	b1->f_unmap();
}



template<typename T>
inline T* f_buf_map板载缓存(S_结构指针 obj) {
	((S_板载缓存*)obj)->f_map();
	return (T*)(((S_板载缓存*)obj)->m_mappedPtr);
}
template<typename T>
inline T* f_buf_map板载缓存(S_板载缓存* obj) {
	(obj)->f_map();
	return (T*)(obj->m_mappedPtr);
}


inline void f_buf_unmap板载缓存(S_结构指针 obj) {
	((S_板载缓存*)obj)->f_unmap();
}
inline void f_buf_unmap板载缓存(S_板载缓存* obj) {
	obj->f_unmap();
}





template<typename T>
void f_buf_append板载缓存(S_板载缓存* obj, const T& data) {
	f_buf_resize(obj, obj->m_Size + 1);

	obj->f_map();
	((T*)obj->m_mappedPtr)[obj->m_Size-1] = data;
	obj->f_unmap();
}

template<typename T>
void f_buf_push_back(S_板载缓存* obj, const std::vector<T>& data) {
	uint64 i = obj->m_Size;
	if (!data.size()) return;

	f_buf_resize(obj, obj->m_Size + data.size());
	
	obj->f_map();
	const T* p = data.data();
	memcpy((void*)&(((T*)obj->m_mappedPtr)[i]), p, data.size() * sizeof(T));
	obj->f_unmap();
}



template<typename T>
uint64 f_板载缓存_remove(S_板载缓存* obj, uint64 offset) {
	((T*)obj->m_mappedPtr)[offset] = ((T*)obj->m_mappedPtr)[obj->m_Size-1];
	--obj->m_Size;
	return obj->m_Size;
}


template<typename T>
uint64 f_板载缓存_remove(S_板载缓存* obj, uint32* id, uint32 num) {
	if (obj->m_Size <= 1) {
		obj->m_Size = 0;
		return 0;
	}
	uint32 末尾ID = obj->m_Size;
	auto 删除部件 = f_DT_末尾删除法移除数据<T>((T*)obj->m_mappedPtr, 末尾ID, id, num);
	obj->m_Size = 末尾ID;
	return obj->m_Size;
}


template<typename T>
uint64 f_板载缓存_remove段_swapEnd(S_板载缓存* obj, uint32 offset, uint32 num) {
	if (obj->m_Size <= num) {
		obj->m_Size = 0;
		return 0;
	}
	uint32 末尾ID = obj->m_Size - num;


	T* data = (T*)obj->m_mappedPtr;
	memcpy(&data[offset], &data[末尾ID], num * sizeof(T));
	
	obj->m_Size = 末尾ID;
	return obj->m_Size;
}

template<typename T>
uint64 f_buf_remove段_swapEnd(S_板载缓存* obj, uint32* id, uint64 num, uint64 offset) {
	if (obj->m_Size <= offset) {
		obj->m_Size = 0;
		return 0;
	}
	uint64 末尾ID = obj->m_Size;
	f_DT_末尾删除法移除数据组<T>((T*)obj->m_mappedPtr, 末尾ID, id, num, offset);
	obj->m_Size = 末尾ID * offset;
	return obj->m_Size;
}

inline void f_板载缓存_pop(S_板载缓存* obj, uint64 num) {
	obj->m_Size -= num;
}

Inline uint8* f_buf_at(S_板载缓存* buf, uint32 ID, uint32 offset) {
	return &((uint8*)buf->m_mappedPtr)[ID * offset];
}

//EngineAPI_EXPORT void f_popend板载缓存(S_板载缓存* obj, int64 id=-1);

EngineAPI_EXPORT void f_clear板载缓存(S_板载缓存* obj);

EngineAPI_EXPORT void f_buf_insert(S_板载缓存* obj, int64 offset, const void* data, uint32 size);









Inline void f_buf_erase(S_GPU内存块& 块, uint32 开始偏移, uint32 数量 = 1) {
	if (块.m_Mem.m_数量) {
		S_GPU内存块 新块 = f_bm_alloc(块.m_Buf, 块.m_Mem.m_数量 - 数量);

		uint8* scr = &(((uint8*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 * 块.m_Buf->m_Offset]);
		uint8* dst = &(((uint8*)新块.m_Buf->m_mappedPtr)[新块.m_Mem.m_偏移 * 新块.m_Buf->m_Offset]);
		memcpy(dst, scr, 开始偏移 * 块.m_Buf->m_Offset);

		dst = &dst[开始偏移 * 块.m_Buf->m_Offset];
		scr = &scr[(开始偏移 + 数量) * 块.m_Buf->m_Offset];
		memcpy(dst, scr, (块.m_Mem.m_数量 - (开始偏移 + 数量)) * 块.m_Buf->m_Offset);

		f_buf_gfree(块.m_Buf, 块.m_Mem);
		块 = 新块;
	}
}

Inline void f_gbuf_fill(S_GPU内存块& 块, const void* src, uint32 指针偏移, uint32 size) {
	f_bm_resize(块, size);

	块.m_Buf->m_分配块内存锁.lock();

	uint8* dst = &( ((uint8*)块.m_Buf->m_mappedPtr)[(块.m_Mem.m_偏移 * 块.m_Buf->m_Offset) + (指针偏移 * 块.m_Buf->m_Offset)] );
	memcpy(dst, src, size * 块.m_Buf->m_Offset);

	块.m_Buf->m_分配块内存锁.unlock();
}

Inline void f_bm_fill(S_GPU内存块& 块, const uint8* src, uint32 size) {
	uint8* dst = &(((uint8*)块.m_Buf->m_mappedPtr)[ (块.m_Mem.m_偏移 * 块.m_Buf->m_Offset) ]);
	memcpy(dst, src, size * 块.m_Buf->m_Offset);
}

Inline void f_bm_fill(S_GPU内存块& 块, const void* src, uint32 size, uint32 指针偏移 = 0) {
	f_bm_resize(块, size);
	std::lock_guard<std::mutex> guard(块.m_Buf->m_分配块内存锁);
	f_bm_fill(块, (uint8*)src, size);
}



Inline void f_buf_down(const S_GPU内存块& 块, S_Array* dst) {
	f_core_array_resize(dst, 块.m_Mem.m_数量);
	uint8* src = &(((uint8*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 * 块.m_Buf->m_Offset]);
	memcpy(dst->ptr_userData, src, 块.m_Mem.m_数量 * 块.m_Buf->m_Offset);
}

void f_bm_copy(S_GPU内存块& dst块, const S_GPU内存块& src块);


Inline uint32 f_buf_offset(const S_GPU内存块& 块) {
	return 块.m_Mem.m_偏移;
}

Inline float32& f_buf_F32_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	assert(offset < 块.m_Mem.m_数量);
	return (((float32*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline float32* f_buf_F32_ptr(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	assert(offset < 块.m_Mem.m_数量);
	return &(((float32*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}

Inline int32& f_buf_I32_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	assert(offset < 块.m_Mem.m_数量);
	return (((int32*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline int32* f_buf_I32_ptr(const S_GPU内存块& 块) {
	assert(块.m_Mem.m_数量);
	return &(((int32*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}
Inline uint32& f_buf_UI32_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	assert(offset < 块.m_Mem.m_数量);
	return (((uint32*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline uint32* f_buf_UI32_ptr(const S_GPU内存块& 块) {
	assert(块.m_Mem.m_数量);
	return &(((uint32*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}

Inline vec2& f_buf_Vec2_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	return ((vec2*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset];
}
Inline vec2* f_buf_Vec2_ptr(const S_GPU内存块& 块) {
	assert(块.m_Mem.m_数量);
	return &(((vec2*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}


Inline uvec2& f_buf_uVec2_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	return ((uvec2*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset];
}
Inline uvec2* f_buf_uVec2_ptr(const S_GPU内存块& 块) {
	assert(块.m_Mem.m_数量);
	return &(((uvec2*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}


Inline vec3& f_buf_Vec3_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	return ((vec3*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset];
}
Inline vec3* f_buf_Vec3_ptr(const S_GPU内存块& 块) {
	assert(块.m_Mem.m_数量);
	return &(((vec3*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}



Inline ivec2& f_buf_iVec2_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	return ((ivec2*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset];
}
Inline ivec2* f_buf_iVec2_ptr(const S_GPU内存块& 块) {
	assert(块.m_Mem.m_数量);
	return &(((ivec2*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}



Inline ivec3& f_buf_iVec3_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	return ((ivec3*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset];
}
Inline ivec3* f_buf_iVec3_ptr(const S_GPU内存块& 块) {
	assert(块.m_Mem.m_数量);
	return &(((ivec3*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}



Inline uvec3& f_buf_uVec3_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	return ((uvec3*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset];
}
Inline uvec3* f_buf_uVec3_ptr(const S_GPU内存块& 块) {
	assert(块.m_Mem.m_数量);
	return &(((uvec3*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}


Inline vec4& f_buf_Vec4_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	return ((vec4*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset];
}
Inline vec4* f_buf_Vec4_ptr(const S_GPU内存块& 块) {
	assert(块.m_Mem.m_数量);
	return &(((vec4*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}

Inline S_VN* f_buf_VN_ptr(const S_GPU内存块& 块) {
	assert(块.m_Mem.m_数量);
	return &(((S_VN*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}
Inline S_VC* f_buf_VC_ptr(const S_GPU内存块& 块) {
	assert(块.m_Mem.m_数量);
	return &(((S_VC*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}
Inline S_VNT1* f_buf_VNT_ptr(const S_GPU内存块& 块) {
	assert(块.m_Mem.m_数量);
	//if(!(块.m_Buf->m_mappedPtr)) 块.m_Buf->f_map();
	return &(((S_VNT1*)(块.m_Buf->m_mappedPtr))[块.m_Mem.m_偏移]);
}


Inline Mat44f& f_buf_Mat44_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	assert(offset < 块.m_Mem.m_数量);
	return ((Mat44f*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset];
}
Inline Mat44f* f_buf_Mat44_ptr(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return &(((Mat44f*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}

Inline mat3X2* f_buf_Mat3X2_ptr(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return &(((mat3X2*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline mat3X2& f_buf_Mat3X2_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	assert(offset < 块.m_Mem.m_数量);
	return (((mat3X2*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}

Inline mat3* f_bm_Mat3_ptr(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return &(((mat3*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline mat3& f_bm_Mat3_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	assert(offset < 块.m_Mem.m_数量);
	return (((mat3*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}


Inline S_2D图元顶点& f_buf_图元顶点_at(const S_GPU内存块& 块, uint32 offset) {
	assert(offset < 块.m_Mem.m_数量);
	return (((S_2D图元顶点*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_2D图元顶点* f_buf_图元顶点_ptr(const S_GPU内存块& 块) {
	assert(块.m_Mem.m_数量);
	return &(((S_2D图元顶点*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}

Inline S_TextueProp& f_buf_纹理属性_at(const S_GPU内存块& 块, uint32 offset) {
	assert(offset < 块.m_Mem.m_数量);
	return (((S_TextueProp*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_TextueProp* f_buf_纹理属性_ptr(const S_GPU内存块& 块) {
	assert(块.m_Mem.m_数量);
	return &(((S_TextueProp*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}


Inline S_LineProp* f_buf_线属性_ptr(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return &(((S_LineProp*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_LineProp& f_buf_线属性_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(offset < 块.m_Mem.m_数量);
	return (((S_LineProp*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}


Inline S_ColorGradient& f_buf_渐变属性_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	assert(offset < 块.m_Mem.m_数量);
	return (((S_ColorGradient*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_ColorGradient* f_buf_渐变属性_ptr(const S_GPU内存块& 块) {
	return &(((S_ColorGradient*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}


Inline S_VkDrawIndirectCommand& f_buf_Indirect_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_偏移 + offset < 块.m_Buf->m_Size);
	assert(offset < 块.m_Mem.m_数量);
	return ((S_VkDrawIndirectCommand*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset];
}
Inline S_VkDrawIndirectCommand* f_buf_Indirect_ptr(const S_GPU内存块& 块) {
	assert(块.m_Mem.m_数量);
	return &(((S_VkDrawIndirectCommand*)(块.m_Buf->m_mappedPtr))[块.m_Mem.m_偏移]);
}

Inline S_VkDrawIndexedIndirectCommand& f_buf_at_IndexIndirect(const S_GPU内存块& 块, uint32 offset) {
	assert(offset < 块.m_Mem.m_数量);
	assert(块.m_Mem.m_数量);
	return ((S_VkDrawIndexedIndirectCommand*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset];
}



Inline S_MeshTranformProp* f_buf_网格元素变换属性_ptr(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return &(((S_MeshTranformProp*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_MeshTranformProp& f_buf_网格元素变换属性_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(offset < 块.m_Mem.m_数量);
	return (((S_MeshTranformProp*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}



Inline S_FaceElement* f_buf_面元素_ptr(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return &(((S_FaceElement*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_FaceElement& f_buf_面元素_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(offset < 块.m_Mem.m_数量);
	return (((S_FaceElement*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}


Inline S_ObMesh* f_buf_网格引用_ptr(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return &(((S_ObMesh*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_ObMesh& f_buf_网格引用_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(offset <= 块.m_Mem.m_偏移);
	return (((S_ObMesh*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}


Inline S_VertBone* f_buf_顶点骨骼_ptr(const S_GPU内存块& 块) {
	assert(块.m_Mem.m_数量);
	return &(((S_VertBone*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}

Inline S_BoneMap* f_buf_骨骼权重_ptr(const S_GPU内存块& 块) {
	assert(块.m_Mem.m_数量);
	return &(((S_BoneMap*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}

Inline S_BonePose* f_buf_骨骼姿态_ptr(const S_GPU内存块& 块) {
	assert(块.m_Mem.m_数量);
	return &(((S_BonePose*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移]);
}


Inline S_CurvePoint2* f_buf_曲线段_ptr(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return &(((S_CurvePoint2*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_CurvePoint2& f_buf_曲线段_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(offset < 块.m_Mem.m_数量);
	return (((S_CurvePoint2*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}




Inline S_CustomAttr* f_buf_自定义属性_ptr(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return &(((S_CustomAttr*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_CustomAttr& f_buf_属性索引_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(offset < 块.m_Mem.m_数量);
	return (((S_CustomAttr*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}

Inline S_LightPoint* f_buf_点光源_ptr(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return &(((S_LightPoint*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}


Inline S_PBF_Params& f_buf_PBF解算参数_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return (((S_PBF_Params*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_PBF_Params* f_buf_PBF解算参数_ptr(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return &(((S_PBF_Params*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_GlobalParam* f_buf_全局GPU参数指针_ptr(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return &(((S_GlobalParam*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}



Inline S_Material& f_buf_Material_at(const S_GPU内存块& 块, uint32 offset) {
	assert(块.m_Mem.m_数量);
	return (((S_Material*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_Material* f_buf_Material_ptr(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return &(((S_Material*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}



Inline S_CurvePoint3D& f_buf_CurvePoint3D_at(const S_GPU内存块& 块, uint32 offset) {
	assert(块.m_Mem.m_数量);
	return (((S_CurvePoint3D*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_CurvePoint3D* f_buf_CurvePoint3D_ptr(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return &(((S_CurvePoint3D*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}


Inline S_2D线& f_bm_2D线_at(const S_GPU内存块& 块, uint32 offset) {
	assert(块.m_Mem.m_数量);
	return (((S_2D线*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
Inline S_2D线* f_bm_2D线_ptr(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return &(((S_2D线*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}






template<typename T>
Inline T& f_bm_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return (((T*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}
template<typename T>
Inline T* f_bm_ptr(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return &(((T*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}

Inline const void* f_bm_Address(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return &( ((uint8*)(块.m_Buf->m_mappedPtr))[(块.m_Mem.m_偏移 + offset) * 块.m_Buf->m_Offset] );
}
Inline void* f_bm_Address(S_GPU内存块& 块, uint32 offset = 0) {
	assert(块.m_Mem.m_数量);
	return &(((uint8*)(块.m_Buf->m_mappedPtr))[(块.m_Mem.m_偏移 + offset) * 块.m_Buf->m_Offset]);
}



template<typename T>
void f_buf_push_back(S_GPU内存块& obj, const std::vector<T>& data) {
	uint64 i = obj.m_Mem.m_数量;
	if (!data.size()) return;
	assert(sizeof(T) == obj.m_Buf->m_Offset);

	f_bm_resize(obj, i+data.size());

	const T* p = data.data();
	uint8* Dst = &(((uint8*)(obj.m_Buf->m_mappedPtr))[(obj.m_Mem.m_偏移+i)*obj.m_Buf->m_Offset]);
	memcpy(Dst, p, data.size() * sizeof(T));
}

Inline void f_bm_push_back(S_GPU内存块& m, const void* data, uint32 num) {
	uint64 原数量 = m.m_Mem.m_数量;
	if (!num) return;

	f_bm_resize(m, 原数量 + num);

	uint8* Dst = &(((uint8*)(m.m_Buf->m_mappedPtr))[(m.m_Mem.m_偏移 + 原数量) * m.m_Buf->m_Offset]);
	memcpy(Dst, data, num * m.m_Buf->m_Offset);
}

Inline void f_buf_push_back(S_GPU内存块& m, const uint8* data, uint32 num) {
	f_bm_push_back(m, data, num);
}

EngineAPI_EXPORT void f_bm_insert(S_GPU内存块& m, uint32 插入位置, const uint8* data, uint32 num);
EngineAPI_EXPORT void f_bm_insert(S_GPU内存块& m, const S_GPU内存块& data, uint32 offset);
EngineAPI_EXPORT void f_bm_remove(S_GPU内存块& m, uint32 删除位置);


template<typename T>
Inline T& f_buf_T元素_at(const S_GPU内存块& 块, uint32 offset = 0) {
	assert(offset < 块.m_Mem.m_数量);
	return (((T*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 + offset]);
}

template<typename T>
T& f_buf_at(S_板载缓存* buf, uint32 offset) {
	return (((T*)buf->m_mappedPtr)[offset]);
}


void f_bm_刷新GPU内存(S_板载缓存* buf);
EngineAPI_EXPORT uint64 f_buf_getOffsetAddress(S_GPU内存块& 块, uint64 offset = 0);
EngineAPI_EXPORT uint64 f_buf_getAddress2(S_GPU内存块& 内存块);
EngineAPI_EXPORT uint64 f_buf_getAddress(S_板载缓存* buf);



//加速结构 不是指针
EngineAPI_EXPORT void* f_buf_get加速结构(S_GPU内存块& 块);
EngineAPI_EXPORT void* f_buf_get加速结构(S_GPU内存块& 块, uint32 offset, uint32 count);
EngineAPI_EXPORT uint64 f_buf_get加速结构(S_板载缓存* buf);


Inline uint8* f_bm_起始指针(const S_GPU内存块& 块) {
	return &((uint8*)块.m_Buf->m_mappedPtr)[块.m_Mem.m_偏移 * 块.m_Buf->m_Offset];
}



//================================  工具扩展函数  ====================================

//void f_buf_resize(uint64 count, uint16 num, ...);


//using t_VertArray = std::vector<S_VNTC, C_VkStagingAllocator<S_VNTC>>;

template<typename T>
class C_vectorGPU : public std::vector<T, C_VkStagingAllocator<T>> {
	

public:
	using Parent = std::vector<T, C_VkStagingAllocator<T>>;
	using Allocator = C_VkStagingAllocator<T>;

	C_vectorGPU(S_板载缓存* buf) : Parent(0, Allocator(buf)) {
		
	}
	C_vectorGPU(uint64 init_size, S_板载缓存* buf) : Parent(init_size, Allocator(buf)) {
		
	}
};


//template<typename T>
//void f_bm_push_back(S_GPU内存块& obj, const std::vector<T>& data) {
//	uint64 i = obj.m_Mem.m_数量;
//	if (!data.size()) return;
//
//	f_bm_resize(obj, i + data.size());
//
//	const T* p = data.data();
//	uint8* Dst = &(((uint8*)(obj.m_Buf->m_mappedPtr))[(obj.m_Mem.m_偏移 + i) * obj.m_Buf->m_Offset]);
//	memcpy(Dst, p, data.size() * sizeof(T));
//}

class C_缓存列队数据 {

protected:
	S_GPU内存块* m_拷贝目标{};
public:
	operator S_板载缓存* () {
		return m_拷贝目标->m_Buf;
	}

	virtual S_GPU偏移大小 f_分配空间() = 0;
	virtual void f_拷贝到GPU() = 0;
};


void f_bm_添加更新缓存列队(std::unique_ptr<C_缓存列队数据>&& data);

void f_bm_刷新缓存到GPU();



